// Feature_MFCC.h: interface for the CFeature_MFCC class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_FEATURE_MFCC_H__AB349ED9_3893_435D_9A84_69BE23875D51__INCLUDED_)
#define AFX_FEATURE_MFCC_H__AB349ED9_3893_435D_9A84_69BE23875D51__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "LXH_Feature.h"

typedef struct{
   int frameSize;			/* speech frameSize */
   int numChans;			/* number of channels */
   long sampPeriod;			/* sample period */
   int fftN;				/* fft size */
   int klo,khi;				/* lopass to hipass cut-off fft indices */
   BOOL usePower;			/* use power rather than magnitude */
   BOOL takeLogs;			/* log filterbank channels */
   float fres;				/* scaled fft resolution */
   FloatVec cf;				/* array[1..pOrder+1] of centre freqs */
   ShortVec loChan;			/* array[1..fftN/2] of loChan index */
   FloatVec loWt;			/* array[1..fftN/2] of loChan weighting */
   FloatVec x;				/* array[1..fftN] of fftchans */
}FBankInfo;

#define Mel(k,fres) float(1127*log(1+(k-1)*fres))
#define	LOPASS			50 
#define	HIPASS			5500

class CFeature_MFCC : public CFeature  
{
public:
	static float MFCCdistance(CData Unit1, CData Unit2);
	CData * FBank2MelCep(const float *fbank_vec, const int fbank_len, const int nMFCCNumber, const float liftering_parameter, const bool include_c0 = true);
	CData * FBank2MelCep(CData &fbank);
	float Hz2Mel(float frequency_in_Hertz);
	float Mel2Hz(float frequency_in_Mel);
	void Weight(CData &data);
	CData *Signal2FBank(const float *sig, int sig_len, const int sample_rate,const int fbank_len, const bool use_power_rather_than_energy = true, const bool take_log = true);
	CData *Signal2FBank(int nNumOfBanks);	
	
	CFeature_MFCC();
	virtual ~CFeature_MFCC();

	virtual CData* ExtractFeature();

protected:
	float* make_mel_triangular_filter(const float this_mel_centre,const float this_mel_low,const float this_mel_high,const float Hz_per_fft_coeff,const int half_fft_order,int &fft_index_start, int &fil_len);
	void FFT2FBank(float *fft_frame, int fft_len, float *fbank_vec, int fbank_len, float Hz_per_fft_coeff, const float *mel_fbank_frequencies, int mbank_len);
};

#endif // !defined(AFX_FEATURE_MFCC_H__AB349ED9_3893_435D_9A84_69BE23875D51__INCLUDED_)
